package com.happok.onlineclass.usermanagement.authentication.config.filter;

import com.happok.common.exception.BusinessException;
import com.happok.onlineclass.usermanagement.authentication.config.exception.ValidateCodeException;
import com.happok.onlineclass.usermanagement.authentication.dto.UserDetailsDTO;
import com.happok.onlineclass.usermanagement.common.dto.SecurityConstants;
import com.happok.onlineclass.usermanagement.common.exception.PreconditionFailedException;
import com.happok.onlineclass.usermanagement.setting.dto.FunctionClassifyEnum;
import com.happok.onlineclass.usermanagement.verifycode.service.VerifyCodeService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * [简要描述]:处理图形验证码过滤器
 * [详细描述]:
 *
 * @author:
 * @date: 3:49 PM 2019/10/18
 * @since: JDK 1.8
 */
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {

    private AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private VerifyCodeService verifyCodeService;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain)
            throws ServletException, IOException {

        if (httpServletRequest.getRequestURI().contains(SecurityConstants.LOGIN_PROCESSING_URL_MOBILE)
                && StringUtils.equalsIgnoreCase(httpServletRequest.getMethod(), "post")) {
            try {
                validateSmsCode(httpServletRequest);
            } catch (AuthenticationException e) {
                authenticationFailureHandler.onAuthenticationFailure(httpServletRequest, httpServletResponse, e);
                return;
            }
        }

        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }

    //校验手机验证码
    private void validateSmsCode(HttpServletRequest request) throws ServletRequestBindingException {
        //请求里的手机号和验证码
        String mobileInRequest = request.getParameter("account");
        String codeInRequest = request.getParameter("verifyCode");

        if (ObjectUtils.isEmpty(mobileInRequest) || ObjectUtils.isEmpty(codeInRequest)) {
            throw new BusinessException("参数异常");
        }
        // 判断用户是否存在
        UserDetailsDTO userDetailsDTO = (UserDetailsDTO) userDetailsService.loadUserByUsername(mobileInRequest);
        if (!userDetailsDTO.isEnabled()) {
            throw new DisabledException("账户被禁用");
        }
        // 校验验证码
        try {
            verifyCodeService.checkVerifyCode(mobileInRequest, FunctionClassifyEnum.USER_LOGIN.getFunction(), Integer.parseInt(codeInRequest));
        } catch (PreconditionFailedException e) {
            throw new ValidateCodeException(e.getCode() + "@" + e.getMsg());
        }
    }

    public AuthenticationFailureHandler getAuthenticationFailureHandler() {
        return authenticationFailureHandler;
    }

    public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
        this.authenticationFailureHandler = authenticationFailureHandler;
    }

}
